package com.syuchen.client.udp;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * 案例：基于AQS实现可创建多个条件等待队列的独占式可重入锁
 */
public class MyLock extends AbstractQueuedSynchronizer {

    final ConditionObject newCondition() {//开放创建等待队列，实现等待/通知机制
        return new ConditionObject();
    }

    @Override
    protected boolean isHeldExclusively() {//判断当前线程是否已独占式持有锁
        return getExclusiveOwnerThread() == Thread.currentThread();
    }


    @Override
    protected boolean tryAcquire(int arg) {
        if (getExclusiveOwnerThread() == Thread.currentThread()) {
            //若尝试获取锁的线程已持有锁，则直接返回true，实现可重入性
            return true;
        }
        //定义锁空闲状态state为0，尝试用CAS操作将其修改为1。多个线程同时竞争时只有一个线程能够修改成功，其余进入同步队列阻塞等待，实现独占性
        if (compareAndSetState(0, 1)) {
            //若修改成功则将exclusiveOwnerThread设置为当前线程
            setExclusiveOwnerThread(Thread.currentThread());
            return true;
        }
        return false;
    }

    @Override
    protected boolean tryRelease(int arg) {
        if (getExclusiveOwnerThread() != Thread.currentThread())
            //若当前线程不持有锁而调用了此方法，则抛出非法监视器状态异常
            throw new IllegalMonitorStateException();
        setExclusiveOwnerThread(null);
        setState(0);//将锁标志置为空闲
        return true;
    }

    public void lock() {//申请锁资源
        acquire(1);
    }

    //可中断的申请锁资源
    public void lockInterruptibly() throws InterruptedException {//申请锁资源
        acquireInterruptibly(1);
    }

    public void unLock() {//释放锁资源
        release(1);
    }
}

